package com.redis.service.impl;

import com.redis.mapper.RedisMapper;
import com.redis.pojo.Redis;
import com.redis.service.RedisService;
import com.redis.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RedisServiceImpl implements RedisService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedisMapper redisMapper;

    @Override
    public List<Redis> findAll() {
        List<Redis> redisList = redisMapper.selectList(null);
        return redisList.subList(1, 10);
    }

    // String数据类型
    @Override
    public List<Redis> findString() {
        List<Redis> redisList = findAll();
        for (Redis redis : redisList) {
            redisTemplate.opsForValue().set(redis.getHid(), redis.getA2() + "   " + redis.getA3(), 10, TimeUnit.HOURS);
        }
        for (Redis redis : redisList) {
            System.out.println("获取: " + redis.getHid() + "   " + redisTemplate.opsForValue().get(redis.getHid()));
        }
        for (Redis redis : redisList) {
            System.out.println("删除: " + redis.getHid() + "   " + redisTemplate.delete(redis.getHid()));
        }
        return redisList;
    }

    // List数据类型
    @Override
    public List<Redis> findList() {
        List<Redis> redisList = findAll();
        //List<String> newList = new ArrayList<>();newList.add(Objects.requireNonNull(JsonUtils.objectToJson(redis)));
        for (Redis redis : redisList) {
            redisTemplate.opsForList().leftPush("redisList", Objects.requireNonNull(JsonUtils.objectToJson(redis)));
        }
        // redisTemplate.opsForList().leftPushAll("redisList", redisList);
//        System.out.println(redisTemplate.opsForList().leftPop("redisList"));
//        System.out.println(redisTemplate.opsForList().index("redisList", 6));
        return redisList;
    }

    // Set数据类型
    @Override
    public List<Redis> findSet() {
        return null;
    }

    // Hash数据类型
    @Override
    public List<Redis> findHash() {
        return null;
    }

    // ZSet数据类型
    @Override
    public List<Redis> findZSet() {
        return null;
    }

    /**
     * 加锁
     *
     * @param key   key值
     * @param value 当前时间 + 超时时间
     * @return boolean
     */
    public boolean lock(String key, String value) {

        if (Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, value))) {
            return true;
        }
        //解决死锁，且当多个线程同时来时，只会让一个线程拿到锁
        String currentValue = stringRedisTemplate.opsForValue().get(key);
        log.info("一个线程拿到锁："+currentValue);
        //如果过期
        if (!StringUtils.isEmpty(currentValue) &&
                Long.parseLong(currentValue) < System.currentTimeMillis()) {
            //获取上一个锁的时间
            String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);
            log.info("上一个锁的时间："+oldValue);
            if (StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 解锁
     *
     * @param key *
     * @param value *
     */
    public void unlock(String key, String value) {

        try {
            String currentValue = stringRedisTemplate.opsForValue().get(key);
            if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
                redisTemplate.opsForValue().getOperations().delete(key);
            }
        } catch (Exception e) {
            log.error("【redis锁】解锁失败, {}", e);
        }
    }
}
